import 'dart:convert';

import 'package:event_bus/event_bus.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:todo_app/controllers/definitions/MessageModel.dart';
import 'package:todo_app/pages/message/definitions/WrapMessage.dart';
import 'package:todo_app/utils/mqtt/MessageDBUtils.dart';
import 'package:todo_app/utils/mqtt/LocalMqttClient.dart';
import 'package:uuid/uuid.dart';
import 'package:uuid/uuid_util.dart';

var uuid = const Uuid();

enum MessageResponseType {
  publishedMsg("PUBLISHED_MSG", 0),
  sendMsg("SEND_MSG", 1),
  receivedMsg("RECEIVED_MSG", 2),
  sendMsgError("SEND_MSG_ERROR", 3);

  const MessageResponseType(this.name, this.value);
  final String name;
  final int value;
}

class MessageResponse {
  final MessageResponseType type;
  final LocalMessage payload;

  MessageResponse({ required this.type, required this.payload });
}

class MessageEventBus {
  static EventBus eventBus = EventBus();

  // 发送消息
  static sendMessage(LocalMessage msg) {
    eventBus.fire(MessageResponse( type: MessageResponseType.sendMsg, payload: msg ));
    // 本地数据库做一次存储
    MessageDBUtils.saveMessage(msg);
    // 构建Payload
    var message = MessageModel()..fromJson(msg.toJson());
    LocalMqttClient.publishMessage(msg.topic, message);
  }
  // 发送文本消息
  static sendTextMessage(int sendUid, MessageCategory category, int receivedId, String content) {
    DateTime sendTime = DateTime.now();
    var msgId =  "${uuid.v4(options: { 'rng': UuidUtil.cryptoRNG })}-${DateTime.now().millisecondsSinceEpoch}";
    var msg = LocalMessage()
      ..mid = msgId
      ..send_time = sendTime.millisecondsSinceEpoch
      ..suid = sendUid
      ..category = category.name
      ..rid = receivedId
      ..content = content
      ..crypto = MessageCrypto.plaintext.name
      ..type = MessageType.text.name
      ..sending = true
      ..sendError = false
      ..viewType = ViewMessageType.message
      ..userId = sendUid;

    MessageEventBus.sendMessage(msg);
  }
  // 再次发送消息
  static sendMessageAgain(LocalMessage msg) {
    msg.sending = true;
    msg.sendError = false;
    MessageEventBus.sendMessage(msg);
  }

  static publishedMessage(MqttPublishMessage publishMessage) {
    final String pt = const Utf8Decoder().convert(publishMessage.payload.message);
    final json = jsonDecode(pt);
    print("自己发送的消息");
    var msg = LocalMessage()..fromJson(json);
    msg.sending = false;
    eventBus.fire(MessageResponse( type: MessageResponseType.publishedMsg, payload: msg ));
    // 本地数据库做一次存储
    MessageDBUtils.saveMessage(msg);
  }

  // 接收到普通消息
  static receivedMessage(MqttPublishMessage recMess) {
    var topic = recMess.variableHeader!.topicName;
    var userId = int.tryParse(topic.replaceAll("/r/", ""));
    if(userId == null) return;
    final pt = const Utf8Decoder().convert(recMess.payload.message);
    final json = jsonDecode(pt);
    var message = MessageModel()..fromJson(json);

    var msg = LocalMessage()..fromJson(message.toJson());
    msg.userId = userId;
    msg.viewType = ViewMessageType.message;
    eventBus.fire(MessageResponse( type: MessageResponseType.receivedMsg, payload: msg ));
    // 本地数据库做一次存储
    MessageDBUtils.saveMessage(msg);
  }
}

enum MessageCategory {
  group("GROUP"),
  single("SINGLE");

  const MessageCategory(this.name);
  final String name;
}


enum MessageType {
  text("TEXT"),
  image("IMAGE"),
  video("VIDEO");

  const MessageType(this.name);
  final String name;
}

enum MessageCrypto {
  plaintext("plaintext"),
  base64("base64"),
  json("json"),
  hex("hex"),
  sha1("sha1"),
  sha128("sha128"),
  sha256("sha256"),
  md5("md5");

  const MessageCrypto(this.name);
  final String name;
}